using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

namespace cmd
{
    [DisallowMultipleComponent]
    public sealed class PickableItemDataManager : SerializedMonoBehaviour
    {
        #region 常量
        public const string PICKABLEITEM_MODELS_PATH = "PickableItemModels";
        public const string FISHTYPES_PATH = "FishTypes";
        #endregion

        #region 单例
        [field: SerializeField, Required]
        public PickableItemDataManager Instance { get; private set; }

        #endregion

        #region 统计
        [field: ShowInInspector, ReadOnly, Space(20)]
        public static int PickableItemDatasCount { get; set; } = 0;

        [field: ShowInInspector, ReadOnly]
        public static int FishTypeDatassCount { get; set; } = 0;

        [field: ShowInInspector, ReadOnly, Space(20)]
        public static Dictionary<PickableItemType, uint> MaxPickableItemDataId { get; set; } =
            new() { [PickableItemType.Fish] = 0, [PickableItemType.Item] = 0 };

        [field: ShowInInspector, ReadOnly]
        public static uint MaxFishTypeDataId { get; set; } = 0;

        #endregion

        /// <summary>
        /// 从Resources文件夹加载所有鱼模型SO
        /// </summary>
        [Button, PropertySpace(10)]
        public static PickableItemDataModelSO[] LoadPickableItemDataModelSOs()
        {
            // 加载Resources/FishModels文件夹下的所有SO文件
            PickableItemDataModelSO[] fishModelSOs = Resources.LoadAll<PickableItemDataModelSO>(
                PICKABLEITEM_MODELS_PATH
            );

            PickableItemDatasCount = fishModelSOs.Length;
            MaxPickableItemDataId[PickableItemType.Fish] = fishModelSOs
                .Where(x => x.PickableItemDataModel.PickableItemType == PickableItemType.Fish)
                .Max(x => x.Id);
            MaxPickableItemDataId[PickableItemType.Item] = fishModelSOs
                .Where(x => x.PickableItemDataModel.PickableItemType == PickableItemType.Item)
                .Max(x => x.Id);

            // 初始化鱼模型数据字典
            // foreach (FishDataModelSO fishModelSO in fishModelSOs)
            // {
            //     Debug.Log($"Loaded fish model: {fishModelSO.name}");
            // }

            return fishModelSOs;
        }

        /// <summary>
        /// 从Resources文件夹加载所有鱼类别SO
        /// </summary>
        [Button, PropertySpace(10)]
        public static FishTypeDataSO[] LoadFishTypeDataSOs()
        {
            // 加载Resources/FishTypes文件夹下的所有SO文件
            FishTypeDataSO[] fishTypeSOs = Resources.LoadAll<FishTypeDataSO>(FISHTYPES_PATH);

            FishTypeDatassCount = fishTypeSOs.Length;
            MaxFishTypeDataId = fishTypeSOs.Max(x => x.FishTypeData.Id);

            // 初始化鱼类别数据字典
            // foreach (FishTypeSO fishTypeSO in fishTypeSOs)
            // {
            //     Debug.Log($"Loaded fish type: {fishTypeSO.name}");
            // }

            return fishTypeSOs;
        }

        /// <summary>
        /// 检查鱼类型Id是否有重复
        /// </summary>
        /// <param name="logIfNoDuplicate">当没有重复时是否打印信息</param>
        public static void CheckDuplicateFishTypeIds(bool logIfNoDuplicate = true)
        {
            FishTypeDataSO[] fishTypeSOs = LoadFishTypeDataSOs();

            var duplicateIds = fishTypeSOs
                .GroupBy(x => x.FishTypeData.Id)
                .Where(g => g.Count() > 1)
                .Select(g => g.Key);

            if (!duplicateIds.Any())
            {
                if (logIfNoDuplicate)
                {
                    Debug.Log("没有发现鱼类型存在重复Id");
                }
                return;
            }

            // 如果有重复的Id，输出警告
            foreach (var id in duplicateIds)
            {
                var duplicates = fishTypeSOs.Where(x => x.FishTypeData.Id == id);
                Debug.LogWarning($"发现重复的鱼类型Id: {id}");
                foreach (var duplicate in duplicates)
                {
                    Debug.LogWarning($"- {id}  {duplicate.name}");
                }
            }
        }

        /// <summary>
        /// 检查鱼类型Id是否有重复
        /// </summary>
        [Button(ButtonSizes.Medium), PropertySpace(10)]
        public static void CheckDuplicateFishTypeIds() => CheckDuplicateFishTypeIds(true);

        /// <summary>
        /// 检查可拾取物品Id是否有重复
        /// </summary>
        /// <param name="logIfNoDuplicate">当没有重复时是否打印信息</param>
        public static void CheckDuplicatePickableItemIds(bool logIfNoDuplicate = true)
        {
            // 加载Resources/PickableItems文件夹下的所有SO文件
            PickableItemDataModelSO[] pickableItemSOs = Resources.LoadAll<PickableItemDataModelSO>(
                "PickableItems"
            );

            var duplicateIds = pickableItemSOs
                .GroupBy(x => (x.PickableItemDataModel.PickableItemType, x.Id))
                .Where(g => g.Count() > 1)
                .Select(g => g.Key);

            if (!duplicateIds.Any())
            {
                if (logIfNoDuplicate)
                    Debug.Log("没有发现可拾取物品存在重复Id");
                return;
            }

            // 如果有重复的Id，输出警告
            foreach (var (type, id) in duplicateIds)
            {
                var duplicates = pickableItemSOs.Where(x =>
                    x.PickableItemDataModel.PickableItemType == type && x.Id == id
                );
                Debug.LogWarning($"发现重复的可拾取物品Id: 类型={type}, Id={id}");
                foreach (var duplicate in duplicates)
                {
                    Debug.LogWarning($"- {duplicate.name}");
                }
            }
        }

        [Button(ButtonSizes.Medium), PropertySpace(10)]
        public static void CheckDuplicatePickableItemIds() => CheckDuplicatePickableItemIds(true);
    }
}
